package com.weblog.user.service;

import com.weblog.model.user.Admin;
import com.weblog.model.user.Permission;
import com.weblog.model.user.Role;
import com.weblog.user.dao.AdminDao;
import com.weblog.user.dao.PermissionDao;
import com.weblog.user.dao.RoleDao;
import com.weblog.user.utils.AccessUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.IdWorker;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author MaoLin Wang
 * @date 2019/9/1817:54
 */
@Service
public class RoleService {

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private AdminDao adminDao;

    @Autowired
    private AccessUtil accessUtil;

    @Autowired
    private PermissionDao permissionDao;


    /**
     * 查询角色列表
     *
     * @return
     */
    public List<Role> RoleList() {
        List<Role> list = roleDao.findAll();
        return list;
    }

    /**
     * 添加角色
     *
     * @param role
     */
    @Transactional(rollbackFor = Exception.class)
    public void addRole(Role role) {
        //角色id
        role.setRid(idWorker.nextId() + "");
        //更改角色名
        role.setRname("role_"+role.getRname());
        //创建时间
        role.setCreatetime(new Date());

        String createUserid = (String) request.getAttribute("id");
        //创建人
        role.setCreateuser(adminDao.findById(createUserid).get().getUsername());

        //最后更新时间
        role.setUpdatetime(new Date());

        //默认为非系统角色
        role.setIssystemrole("0");

        role.setAdmins(null);
        roleDao.save(role);
    }

    /**
     * 根据id查询角色信息
     *
     * @param roleid
     * @return
     */
    public Role findRoleById(String roleid) {
        return roleDao.findById(roleid).get();
    }

    /**
     * 根据角色id查询权限列表
     *
     * @param rid
     * @return
     */
    public List<Permission> findPermissionsByRoleId(String rid) {

        Role role = roleDao.findById(rid).get();
        Set<Permission> permissions = role.getPermissions();
        List<Permission> permissionlist = new ArrayList<>(permissions);
        return permissionlist;
    }


    /**
     * 更新角色
     *
     * @param role
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int update(Role role) {
        String token = (String) request.getAttribute("claims_admin");
        boolean has_access = false;
        if (token != null && !"".equals(token)) {
            if ("1".equals(role.getIssystemrole())) {
                //系统角色，无权限修改
                return 2;
            }
            //普通管理员
            int flag = accessUtil.isAccess("role_role", "role_update");
            if (flag == 2) {
                return flag;
            }
            roleDao.save(role);
        }
        roleDao.save(role);
        return 1;
    }

    /**
     * 弃用角色
     *
     * @param rid 角色id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int roleNotUse(String rid) {

        String token = (String) request.getAttribute("claims_admin");
        boolean has_access = false;
        if (token != null && !"".equals(token)) {
            String isSys = roleDao.findIssystemroleByRid(rid);
            if ("1".equals(isSys)) {
                //系统角色，无权限弃用
                return 2;
            }
            //普通管理员
            int flag = accessUtil.isAccess("role_role", "role_delete");
            if (flag == 2) {
                return flag;
            }
            roleDao.changeState(rid, "0");
        }
        roleDao.changeState(rid, "0");
        return 1;
    }

    /**
     * 给角色添加管理员
     *
     * @param rid
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int addAdminToRole(String rid, String id) {
        Role role = roleDao.findById(rid).get();
        Set<Admin> admins = role.getAdmins();
        for (Admin admin : admins) {
            if (id.equals(admin.getId())) {
                //用户已经被分配该角色
                return 0;
            }
        }
        String token = (String) request.getAttribute("claims_admin");
        boolean has_access = false;
        if (token != null && !"".equals(token)) {
            //普通管理员
            int flag = accessUtil.isAccess("role_role", "role_update");
            if (flag == 2) {
                return flag;
            }
            roleDao.addAdminToRole(rid, id);
            return 1;
        }
        roleDao.addAdminToRole(rid, id);
        return 1;
    }

    /**
     * 给角色添加权限
     *
     * @param rid
     * @param pid
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int addPermissionToRole(String rid, String pid) {
        String token = (String) request.getAttribute("claims_admin");
        boolean has_access = false;
        if (token != null && !"".equals(token)) {
            //普通管理员
            int flag = accessUtil.isAccess("role_role", "role_update");
            if (flag == 2) {
                return flag;//权限不足
            }
            int i = IsAllowed(rid, pid,"0","1");
            if (i == 1) {
                roleDao.addPermissionToRole(rid, pid);
                return 1;
            } else {
                /*
                    i=0：重复分配
                    i=3：权限越界
                    i=2：权限不足
                 */
                return i;
            }
        }
        //超级管理员
        int j = IsAllowed(rid, pid,"1","1");
        if (j == 1) {
            roleDao.addPermissionToRole(rid, pid);
            return 1;
        }
        return j;
    }

    /**
     * 是否允许分配权限
     * @param rid 角色id
     * @param pid 权限id
     * @param adminType 管理员类型 0普通 1超级
     * @param type 1添加权限 0取消授权
     * @return
     */
    private int IsAllowed(String rid, String pid,String adminType,String type) {
        Role role = roleDao.findById(rid).get();//待分配权限角色
        Set<Permission> permissions = null;//角色已有权限
        if ("1".equals(role.getIssystemrole())) {
            //操作系统角色
           if("0".equals(adminType)){
               //普通管理员 权限不足
               return 2;
           }
           //超级管理员
            if("1".equals(type)){
                //添加权限
                Permission permission = permissionDao.findById(pid).get();//要添加的权限
                int length=role.getRname().substring(5).length();
                if (!role.getRname().substring(5).equals(permission.getPname().substring(0,length))) {
                    //权限越界，即给角色分配了不属于它的权限
                    return 3;
                }
                System.out.println(role.getRname().substring(4));
                permissions = role.getPermissions();
                for (Permission p : permissions) {
                    if (pid.equals(p.getPid())) {
                        //权限已经被分配该角色
                        return 0;
                    }
                }
                return 1;
            }
            //取消授权
            return 1;

        }
        //操作非系统角色
        if("1".equals(type)){
            //添加权限
            permissions = role.getPermissions();
            for (Permission p : permissions) {
                if (pid.equals(p.getPid())) {
                    //权限已经被分配该角色
                    return 0;
                }
            }
            return 1;
        }
        //取消授权
        return 1;


    }

    /**
     * 根据角色id和权限id删除角色权限
     * @param rid
     * @param pid
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int deletePermissionOfRole(String rid, String pid) {
        String token = (String) request.getAttribute("claims_admin");
        boolean has_access = false;
        if (token != null && !"".equals(token)) {
            //普通管理员
            int flag = accessUtil.isAccess("role_role", "role_update");
            if (flag == 2) {
                return flag;//权限不足
            }
            int i = IsAllowed(rid, pid,"0","0");
            if (i == 1) {
                Role role = roleDao.findById(rid).get();
                Permission permission = permissionDao.findById(pid).get();
                role.getPermissions().remove(permission);
              // roleDao.deletePermissionOfRole(rid,pid);
                return 1;
            } else {
                /*
                    i=2:权限不足
                 */
                return i;
            }
        }
        //超级管理员
        Role role = roleDao.findById(rid).get();
        Permission permission = permissionDao.findById(pid).get();
        role.getPermissions().remove(permission);
        return 1;
    }
}
